热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

都会|坏处_[JS入门到进阶]手写解析uin8数组的工具:解析二进制字节,太快太方便了!

篇首语:本文由编程笔记#小编为大家整理,主要介绍了[JS入门到进阶]手写解析uin8数组的工具:解析二进制字节,太快太方便了!相关的知识,希望对你有一定的参考价值。

篇首语:本文由编程笔记#小编为大家整理,主要介绍了[JS入门到进阶] 手写解析uin8数组的工具:解析二进制字节,太快太方便了!相关的知识,希望对你有一定的参考价值。




背景

我常常需要处理二进制数据,每次面对一堆二进制数据,需要自己逐个字节转换为二进制、十六进制,去阅读和理解,去排查问题。

举个例子:有一个场景是我的《我做了个《联机桌游合集: UNO+斗地主+五子棋》无需下载,点开即玩!叫上朋友,即刻开局!不看广告,不做任务,享受「纯粹」的游戏!》,我使用websocket传输二进制数据,我使用protocol buffer作为序列化协议。所有变量的值都用二进制表示,变量名也被用数字表示,体积很小。(另一种常见的序列化协议是JSON,它是基于文本的序列化协议,空间利用率低,所以常常需要压缩)



  • 使用二进制的好处:空间利用率高,节约带宽,提升速度。

  • 使用二进制的坏处:调试难度高,开发成本高。


诉求

二进制的数据,通常用uin8数组表示。8个二进制位就表示一个byte(十进制的值为0-255,即十六进制的00至FF)。我们调试二进制数据时,也常常看到诸如43 6c 6f 73表示的数据,这是十六进制,每2位十六进制,就代表了一个byte。当然,也有时候使用十进制打印的。

但是十进制、十六进制,都不能满足诉求。

有时候我们需要以二进制表示,直观看清每一位的值。有时候我们需要把整体作为一个整数(例如整体作为uint32),看看它的值。有时候我们需要把每位按照ASCII转换为字符串,也许它是有语义的。


分享工具

网上有些现成的进制转换工具,但都不好用。而且有广告,比较慢。

所以我自己做了一个工具: https://tool.hullqin.cn/byte-parser.html

特性如下:



  • 支持「十进制表示的uint8数组、二进制表示的uint8数组、十六进制表示的uint8数组、整体作为数字、ASCII数组」互相转换。任意输入一项,只要合法,其它项都会自动生成,并且格式化,并且生成的结果你可以随意编辑,再次转换。

  • 如果出错,有错误提示,并保留上一次结果。

  • 如果字节过多(超过6),那么(整体的值)10进制意义不大,就不再计算了。

  • 如果有一个字节不是合法的ASCII,就认为ASCII无意义,就不再计算了。

  • 轻量级、开源,不到200行代码,如有定制化需求,可fork代码后修改。


如何开发

核心html































提前做好dom查询,存储下来,避免以后再查:

let bytes = [];
const bytesEle =
2: document.getElementById(bytes-2),
10: document.getElementById(bytes-10),
16: document.getElementById(bytes-16),
;
const valueIntEle = document.getElementById(value-int);
const valueAsciiEle = document.getElementById(value-ascii);
const messageEle = document.getElementById(message);
const pad =
2: 8,
16: 2,
10: 0,
;

手写setter,即设置bytes的函数:

const setBytes = (value) =>
bytes = value;
console.log(bytes);
Object.keys(bytesEle).forEach(radix =>
const ele = bytesEle[radix];
ele.value = bytes.map(i => i.toString(radix).padStart(pad[radix], 0).padStart(8, )).join( )
);
if (bytes.length > 6)
valueIntEle.value = ;
else
valueIntEle.value = bytes.map((i, index) => i * (256 ** (bytes.length - 1 - index))).reduce((a, b) => a + b).toString();

if (bytes.every(i => (i === 10 || i > 31) && i <127))
valueAsciiEle.value = String.fromCharCode(...bytes);
else
valueAsciiEle.value = ;

;

手写click触发的事件,根据输入内容,生成bytes,然后调用setBytes,触发视图更新:

const changeBytesByUin8 = (value, radix) =>
const newBytes = value.split(/[^\\da-fA-F]+/).filter(i => i !== ).map(i => parseInt(i.trim(), radix));
if (newBytes.findIndex(i => Number.isNaN(i) || i >= 256) >= 0)
throw new Error(解析失败);

setBytes(newBytes);
;
const changeBytesByInt = (value) =>
let num = Number(value.trim());
if (Number.isNaN(num))
throw new Error(解析失败);

const result = [];
while (num > 0)
result.splice(0, 0, num % 256);
num = Math.floor(num / 256);

setBytes(result);
;
const changeBytesByAscii = (value) =>
const result = Array.from(value).map(i => i.charCodeAt(0));
if (result.findIndex(i => i > 256) >= 0)
throw new Error(解析失败);

setBytes(result);
;

把事件绑定到dom上:

const onUint8ValueChange = (radix) => (event) =>
try
messageEle.innerText = ;
changeBytesByUin8(event.target.value.trim(), radix);
catch (e)
messageEle.innerText = e.message;

Object.keys(bytesEle).forEach(radix =>
bytesEle[radix].addEventListener(change, onUint8ValueChange(radix));
);

体验地址 & 源码

体验地址: https://tool.hullqin.cn/byte-parser.html

源码: https://github.com/HullQin/tool-hullqin-cn


写在最后

我是HullQin,公众号线下聚会游戏的作者(欢迎关注公众号,发送加微信,交个朋友),转发本文前需获得作者HullQin授权。我独立开发了《联机桌游合集》,是个网页,可以很方便的跟朋友联机玩斗地主、五子棋等游戏,不收费没广告。还独立开发了《合成大西瓜重制版》。还开发了《Dice Crush》参加Game Jam 2022。喜欢可以关注我 HullQin 噢~我有空了会分享做游戏的相关技术。


推荐阅读
  • 本文介绍了如何在 Node.js 中使用 `setDefaultEncoding` 方法为可写流设置默认编码,并提供了详细的语法说明和示例代码。 ... [详细]
  • 在高并发需求的C++项目中,我们最初选择了JsonCpp进行JSON解析和序列化。然而,在处理大数据量时,JsonCpp频繁抛出异常,尤其是在多线程环境下问题更为突出。通过分析发现,旧版本的JsonCpp存在多线程安全性和性能瓶颈。经过评估,我们最终选择了RapidJSON作为替代方案,并实现了显著的性能提升。 ... [详细]
  • 本文详细介绍了优化DB2数据库性能的多种方法,涵盖统计信息更新、缓冲池调整、日志缓冲区配置、应用程序堆大小设置、排序堆参数调整、代理程序管理、锁机制优化、活动应用程序限制、页清除程序配置、I/O服务器数量设定以及编入组提交数调整等方面。通过这些技术手段,可以显著提升数据库的运行效率和响应速度。 ... [详细]
  • Redux入门指南
    本文介绍Redux的基本概念和工作原理,帮助初学者理解如何使用Redux管理应用程序的状态。Redux是一个用于JavaScript应用的状态管理库,特别适用于React项目。 ... [详细]
  • 本文总结了优化代码可读性的核心原则与技巧,通过合理的变量命名、函数和对象的结构化组织,以及遵循一致性等方法,帮助开发者编写更易读、维护性更高的代码。 ... [详细]
  • 深入解析Java虚拟机(JVM)架构与原理
    本文旨在为读者提供对Java虚拟机(JVM)的全面理解,涵盖其主要组成部分、工作原理及其在不同平台上的实现。通过详细探讨JVM的结构和内部机制,帮助开发者更好地掌握Java编程的核心技术。 ... [详细]
  • 优化网页加载速度:JavaScript 实现图片延迟加载
    本文介绍如何使用 JavaScript 实现图片延迟加载,从而显著提升网页的加载速度和用户体验。 ... [详细]
  • 深入解析动态代理模式:23种设计模式之三
    在设计模式中,动态代理模式是应用最为广泛的一种代理模式。它允许我们在运行时动态创建代理对象,并在调用方法时进行增强处理。本文将详细介绍动态代理的实现机制及其应用场景。 ... [详细]
  • JavaScript中的数组是数据集合的核心结构之一,内置了多种实用的方法。掌握这些方法不仅能提高开发效率,还能显著提升代码的质量和可读性。本文将详细介绍数组的创建方式及常见操作方法。 ... [详细]
  • 本题要求在一组数中反复取出两个数相加,并将结果放回数组中,最终求出最小的总加法代价。这是一个经典的哈夫曼编码问题,利用贪心算法可以有效地解决。 ... [详细]
  • 2018-2019学年第六周《Java数据结构与算法》学习总结
    本文总结了2018-2019学年第六周在《Java数据结构与算法》课程中的学习内容,重点介绍了非线性数据结构——树的相关知识及其应用。 ... [详细]
  • 本文介绍如何使用 Angular 6 的 HttpClient 模块来获取 HTTP 响应头,包括代码示例和常见问题的解决方案。 ... [详细]
  • 基于Node.js、Express、MongoDB和Socket.io的实时聊天应用开发
    本文详细介绍了使用Node.js、Express、MongoDB和Socket.io构建的实时聊天应用程序。涵盖项目结构、技术栈选择及关键依赖项的配置。 ... [详细]
  • 深入理解Vue.js:从入门到精通
    本文详细介绍了Vue.js的基础知识、安装方法、核心概念及实战案例,帮助开发者全面掌握这一流行的前端框架。 ... [详细]
  • 探讨如何修复Visual Studio Code中JavaScript的智能感知和自动完成功能在特定场景下无法正常工作的问题,包括配置检查、语言模式选择以及类型注释的使用。 ... [详细]
author-avatar
Gome--李想
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有